package com.leyou.item.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.dto.PageDTO;
import com.leyou.common.exception.LyException;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 虎哥
 */
@Service
@Transactional
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {
    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SpuDetailService detailService;
    @Autowired
    private SkuService skuService;

    /**
     * 商品分页查询
     * @param brandId
     * @param categoryId
     * @param id
     * @param page
     * @param rows
     * @param saleable
     * @return
     */
    @Override
    public PageDTO<SpuDTO> queryByPage(Long brandId, Long categoryId, Long id, Long page, Long rows, Boolean saleable) {
        //健壮性判断
        page=Math.max(page,1);
        rows=Math.min(rows,5);
        //分页
        Page<Spu> page1 = query()
                .eq(brandId != null, "brand_id", brandId)
                .eq(categoryId != null, "cid3", categoryId)
                .eq(id != null, "id", id)
                .eq(saleable != null, "saleable", saleable)
                .page(new Page<>(page, rows));
        long total = page1.getTotal();
        long totalPage = page1.getPages();
        List<Spu> spuList = page1.getRecords();
        List<SpuDTO> spuDTOList = SpuDTO.convertEntityList(spuList);

        for (SpuDTO spuDTO : spuDTOList) {
            handCategoryNameAndBrand(spuDTO);
        }
        return new PageDTO<SpuDTO>(total,totalPage,spuDTOList);
    }

    /**
     * 转换为商品名称和分类名称
     * @param spuDTO
     */
    private void handCategoryNameAndBrand(SpuDTO spuDTO) {
        //根据品牌id查询品牌名称
        Brand brand = brandService.getById(spuDTO.getBrandId());
        if (brand != null) {
            spuDTO.setBrandName(brand.getName());
        }
        //根据分类id查询分类名称
        List<Category> categoryList = categoryService.listByIds(spuDTO.getCategoryIds());
        if (!CollectionUtils.isEmpty(categoryList)) {
            String name = categoryList.stream()
                    .map(Category::getName).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(name);
        }

    }

    /**
     * 新增商品
     * @param spuDTO
     */
    @Override
    public void saveGoods(SpuDTO spuDTO) {
        //新增spu
        Spu spu = spuDTO.toEntity(Spu.class);
        spu.setSaleable(false);
        boolean success = save(spu);
        if (!success){
            throw new LyException(500,"新增spu失败");
        }
        //新增spuDetail
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        SpuDetail spuDetail = spuDetailDTO.toEntity(SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        success = detailService.save(spuDetail);
        if (!success){
            throw new LyException(500,"新增spuDetail失败");
        }

        List<SkuDTO> skuDTOList = spuDTO.getSkus();
       /* //新增sku
        List<Sku> skuList=new ArrayList<>();
        for (SkuDTO skuDTO : skuDTOList) {
            Sku sku = skuDTO.toEntity(Sku.class);
            sku.setSaleable(false);
            sku.setSpuId(spu.getId());
            skuList.add(sku);
        }
        //批量新增
        skuService.saveBatch(skuList);*/

        //新增sku
        List<Sku> skuList1 = skuDTOList.stream()
                .map(skuDTO -> {
                    Sku sku = skuDTO.toEntity(Sku.class);
                    sku.setSaleable(false);
                    sku.setSpuId(spu.getId());
                    return sku;
                }).collect(Collectors.toList());
        //批量新增
        skuService.saveBatch(skuList1);
    }

    /**
     * 下架商品
     * @param id
     * @param saleable
     */
    @Override
    public void updateSpuSaleable(Long id, Boolean saleable) {
        //更改spu表的saleable
        Spu spu=new Spu();
        spu.setId(id);
        spu.setSaleable(saleable);
        boolean success = updateById(spu);
        if (!success){
            throw new LyException(500,"下架失败");
        }
        //再更新sku表的saleable
        success = skuService.update().eq("spu_id", id).set("saleable", saleable).update();
        if (!success){
            throw new LyException(500,"下架失败");
        }
    }

    @Override
    public void updateGoods(SpuDTO spuDTO) {
        //根据spu的id判断spuDTO中是否包含要修改的spu
        Long spuId = spuDTO.getId();
        if (spuId!=null){ //有需要修改的spu
            Spu spu = spuDTO.toEntity(Spu.class);
            boolean success = updateById(spu);
            if (!success){
                throw new LyException(500,"修改spu失败");
            }

        }

        //根据spu的id判断spuDetail中是否包含要修改的spu
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        if (spuDetailDTO!=null&&spuDetailDTO.getSpuId()!=null){
            SpuDetail spuDetail = spuDetailDTO.toEntity(SpuDetail.class);
            boolean success = detailService.updateById(spuDetail);
            if (!success){
                throw new LyException(500,"修改spuDetail失败");
            }
        }

        //修改sku
        List<SkuDTO> skuDTOList = spuDTO.getSkus();
        //判断sku集合是否为空
        if (CollectionUtils.isEmpty(skuDTOList)){
            return;
        }
        //转换为sku,并根据saleable是否为null来分组,不是null为修改，是null 为删除
        Map<Boolean, List<Sku>> map = skuDTOList.stream()
                .map(skuDTO -> skuDTO.toEntity(Sku.class))
                .collect(Collectors.groupingBy(sku -> sku.getSaleable() == null));
        //获取新增或修改的sku
        List<Sku> insertOrUpdateList = map.get(true);
        if (!CollectionUtils.isEmpty(insertOrUpdateList)){
            skuService.saveOrUpdateBatch(insertOrUpdateList);
        }

        //获取需要删除的sku
        List<Sku> deleteSkuList = map.get(false);
        if (!CollectionUtils.isEmpty(deleteSkuList)){
            List<Long> ids = deleteSkuList.stream()
                    .map(Sku::getId).collect(Collectors.toList());
            skuService.removeByIds(ids);
        }
    }

    /**
     * 商品回显时，需要先根据id查询到商品的spu、sku、spuDetail等信息
     * @param id
     * @return
     */
    @Override
    public SpuDTO queryGoodsById(Long id) {
        //根据id查询spu
        Spu spu = getById(id);
        if (spu==null){
            throw new LyException(500,"spu查询为空");
        }
        SpuDTO spuDTO=new SpuDTO(spu);
        //查询spuDetail
        SpuDetail spuDetail = detailService.getById(id);
        if (spuDetail==null){
            throw new LyException(500,"spuDetail查询为空");
        }
        SpuDetailDTO spuDetailDTO=new SpuDetailDTO(spuDetail);
        spuDTO.setSpuDetail(spuDetailDTO);

        //根据spu_id查询sku的集合
        List<Sku> skuList = skuService.query().eq("spu_id", id).list();
        if (skuList==null){
            throw new LyException(500,"sku查询为空");
        }
        List<SkuDTO> skuDTOList = SkuDTO.convertEntityList(skuList);
        spuDTO.setSkus(skuDTOList);
        //再根据spu_id查询商品名称
        handCategoryNameAndBrand(spuDTO);
        return spuDTO;
    }

}
